home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume18 / undel / part03 < prev    next >
Encoding:
Text File  |  1989-05-06  |  18.2 KB  |  762 lines

  1. Path: uunet!bbn.com!rsalz
  2. From: rsalz@uunet.uu.net (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v18i075:  MIT Athena delete/undelete programs, Part03/06
  5. Message-ID: <1635@fig.bbn.com>
  6. Date: 29 Mar 89 04:32:02 GMT
  7. Lines: 750
  8. Approved: rsalz@uunet.UU.NET
  9.  
  10. Submitted-by: Jonathan I. Kamens <jik@PIT-MANAGER.MIT.EDU>
  11. Posting-number: Volume 18, Issue 75
  12. Archive-name: undel/part03
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then unpack
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of archive 3 (of 6)."
  21. # Contents:  delete.c lsdel.c
  22. # Wrapped by jik@pit-manager on Mon Mar 27 12:16:50 1989
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f 'delete.c' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'delete.c'\"
  26. else
  27. echo shar: Extracting \"'delete.c'\" \(9801 characters\)
  28. sed "s/^X//" >'delete.c' <<'END_OF_FILE'
  29. X/*
  30. X * $Source: /mit/jik/src/delete/RCS/delete.c,v $
  31. X * $Author: jik $
  32. X *
  33. X * This program is a replacement for rm.  Instead of actually deleting
  34. X * files, it marks them for deletion by prefixing them with a ".#"
  35. X * prefix.
  36. X *
  37. X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
  38. X * For copying and distribution information, see the file "mit-copyright.h."
  39. X */
  40. X
  41. X#if (!defined(lint) && !defined(SABER))
  42. X     static char rcsid_delete_c[] = "$Header: delete.c,v 1.17 89/03/27 12:05:58 jik Exp $";
  43. X#endif
  44. X
  45. X#include <sys/types.h>
  46. X#include <stdio.h>
  47. X#include <sys/stat.h>
  48. X#include <sys/dir.h>
  49. X#include <strings.h>
  50. X#include <sys/param.h>
  51. X#include <sys/file.h>
  52. X#include "util.h"
  53. X#include "delete.h"
  54. X#include "mit-copyright.h"
  55. X
  56. X
  57. X
  58. X
  59. X/*
  60. X * ALGORITHM:
  61. X *
  62. X * 1. Parse command-line arguments and set flags.
  63. X * 2. Call the function delete() for each filename command-line argument.
  64. X *
  65. X * delete():
  66. X *
  67. X * 1. Can the file be lstat'd?
  68. X *    no -- abort
  69. X *    yes -- continue
  70. X * 2. Is the file a directory?
  71. X *    yes -- is it a dotfile?
  72. X *           yes -- abort
  73. X *           no -- continue
  74. X *        -- is the filesonly option set?
  75. X *           yes -- is the recursive option specified?
  76. X *                  yes -- continue
  77. X *                  no -- abort
  78. X *           no -- is the directory empty?
  79. X *                  yes -- remove it
  80. X *                  no -- is the directoriesonly option set?
  81. X *               yes -- abort
  82. X *               no -- continue
  83. X *                -- is the recursive option specified?
  84. X *               yes -- continue
  85. X *               no -- abort
  86. X *    no -- is the directoriesonly option set?
  87. X *         yes -- abort
  88. X *         no -- continue
  89. X * 3. If the file is a file, remove it.
  90. X * 4. If the file is a directory, open it and pass each of its members
  91. X *    (excluding . files) to delete().
  92. X */
  93. X
  94. X
  95. Xint force, interactive, recursive, noop, verbose, filesonly, directoriesonly;
  96. Xchar *whoami;
  97. Xchar *malloc();
  98. X
  99. Xmain(argc, argv)
  100. Xint argc;
  101. Xchar *argv[];
  102. X{
  103. X     extern char *optarg;
  104. X     extern int optind;
  105. X     int arg;
  106. X     int status = 0;
  107. X     
  108. X     whoami = lastpart(argv[0]);
  109. X
  110. X     force = interactive = recursive = noop = verbose = filesonly =
  111. X      directoriesonly = 0;
  112. X     while ((arg = getopt(argc, argv, "firnvFD")) != -1) {
  113. X      switch (arg) {
  114. X      case 'r':
  115. X           recursive++;
  116. X           if (directoriesonly) {
  117. X            fprintf(stderr, "%s: -r and -D are mutually exclusive.\n",
  118. X                whoami);
  119. X            usage();
  120. X            exit(! force);
  121. X           }
  122. X           break;
  123. X      case 'f':
  124. X           force++;
  125. X           break;
  126. X      case 'i':
  127. X           interactive++;
  128. X           break;
  129. X      case 'n':
  130. X           noop++;
  131. X           break;
  132. X      case 'v':
  133. X           verbose++;
  134. X           break;
  135. X      case 'F':
  136. X           filesonly++;
  137. X           if (directoriesonly) {
  138. X            fprintf(stderr, "%s: -F and -D are mutually exclusive.\n",
  139. X                whoami);
  140. X            usage();
  141. X            exit(! force);
  142. X           }
  143. X           break;
  144. X      case 'D':
  145. X           directoriesonly++;
  146. X           if (recursive) {
  147. X            fprintf(stderr, "%s: -r and -D are mutually exclusive.\n",
  148. X                whoami);
  149. X            usage();
  150. X            exit(! force);
  151. X           }
  152. X           if (filesonly) {
  153. X            fprintf(stderr, "%s: -F and -D are mutually exclusive.\n",
  154. X                whoami);
  155. X            usage();
  156. X            exit(! force);
  157. X           }
  158. X           break;
  159. X      default:
  160. X           usage();
  161. X           exit(! force);
  162. X      }
  163. X     }
  164. X     if (optind == argc) {
  165. X      fprintf(stderr, "%s: no files specified.\n", whoami);
  166. X      usage();
  167. X      exit(! force);
  168. X     }
  169. X     while (optind < argc) {
  170. X      status = status | delete(argv[optind], 0);
  171. X      optind++;
  172. X     }
  173. X     exit((! force) && (status & ERROR_MASK));
  174. X}
  175. X
  176. X
  177. X
  178. X
  179. Xusage()
  180. X{
  181. X     printf("Usage: %s [ options ] filename ...\n", whoami);
  182. X     printf("Options are:\n");
  183. X     printf("     -r     recursive\n");
  184. X     printf("     -i     interactive\n");
  185. X     printf("     -f     force\n");
  186. X     printf("     -n     noop\n");
  187. X     printf("     -v     verbose\n");
  188. X     printf("     -F     files only\n");
  189. X     printf("     -D     directories only\n");
  190. X     printf("     --     end options and start filenames\n");
  191. X     printf("-r and -D are mutually exclusive\n");
  192. X     printf("-F and -D are mutually exclusive\n");
  193. X}
  194. X
  195. X
  196. X
  197. X
  198. X
  199. X
  200. Xdelete(filename, recursed)
  201. Xchar *filename;
  202. Xint recursed;
  203. X{
  204. X     struct stat stat_buf;
  205. X
  206. X     /* can the file be lstat'd? */
  207. X     if (lstat(filename, &stat_buf) == -1) {
  208. X      if (! force)
  209. X           fprintf(stderr, "%s: %s nonexistent\n", whoami, filename);
  210. X      return(ERROR_MASK);
  211. X     }
  212. X     
  213. X     /* is the file a directory? */
  214. X     if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) {
  215. X      /* is the file a dot file? */
  216. X      if (is_dotfile(filename)) {
  217. X           if (! force)
  218. X            fprintf(stderr, "%s: cannot remove `.' or `..'\n",
  219. X                whoami);
  220. X           return(ERROR_MASK);
  221. X      }
  222. X      /* is the filesonly option set? */
  223. X      if (filesonly) {
  224. X           /* is the recursive option specified? */
  225. X           if (recursive) {
  226. X            return(recursive_delete(filename, stat_buf, recursed));
  227. X           }
  228. X           else {
  229. X            if (! force)
  230. X             fprintf(stderr, "%s: %s directory\n", whoami,
  231. X                 filename);
  232. X            return(ERROR_MASK);
  233. X           }
  234. X      }
  235. X      else {
  236. X           /* is the directory empty? */
  237. X           if (empty_directory(filename)) {
  238. X            /* remove it */
  239. X            return(do_move(filename, stat_buf, 0));
  240. X           }
  241. X           else {
  242. X            /* is the directoriesonly option set? */
  243. X            if (directoriesonly) {
  244. X             if (! force)
  245. X                  fprintf(stderr, "%s: %s: Directory not empty\n",
  246. X                     whoami, filename);
  247. X             return(ERROR_MASK);
  248. X            }
  249. X            else {
  250. X             /* is the recursive option specified? */
  251. X             if (recursive) {
  252. X                  return(recursive_delete(filename, stat_buf,
  253. X                              recursed));
  254. X             }
  255. X             else {
  256. X                  if (! force)
  257. X                   fprintf(stderr, "%s: %s not empty\n",
  258. X                       whoami, filename);
  259. X                  return(ERROR_MASK);
  260. X             }
  261. X            }
  262. X           }
  263. X      }
  264. X     }
  265. X     else {
  266. X      /* is the directoriesonly option set? */
  267. X      if (directoriesonly) {
  268. X           if (! force)
  269. X            fprintf(stderr, "%s: %s: Not a directory\n", whoami,
  270. X                filename);
  271. X           return(ERROR_MASK);
  272. X      }
  273. X      else
  274. X           return(do_move(filename, stat_buf, 0));
  275. X     }
  276. X}
  277. X
  278. X         
  279. X             
  280. X           
  281. Xempty_directory(filename)
  282. Xchar *filename;
  283. X{
  284. X     DIR *dirp;
  285. X     struct direct *dp;
  286. X
  287. X     dirp = opendir(filename);
  288. X     if (! dirp) {
  289. X      return(0);
  290. X     }
  291. X     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
  292. X      if (is_dotfile(dp->d_name))
  293. X           continue;
  294. X      if (is_deleted(dp->d_name))
  295. X           continue;
  296. X      else {
  297. X           closedir(dirp);
  298. X           return(0);
  299. X      }
  300. X     }
  301. X     closedir(dirp);
  302. X     return(1);
  303. X}
  304. X
  305. X
  306. X
  307. X
  308. Xrecursive_delete(filename, stat_buf, recursed)
  309. Xchar *filename;
  310. Xstruct stat stat_buf;
  311. Xint recursed;
  312. X{
  313. X     DIR *dirp;
  314. X     struct direct *dp;
  315. X     int status = 0;
  316. X     char newfile[MAXPATHLEN];
  317. X     
  318. X     if (interactive && recursed) {
  319. X      printf("%s: remove directory %s? ", whoami, filename);
  320. X      if (! yes())
  321. X           return(NO_DELETE_MASK);
  322. X     }
  323. X     dirp = opendir(filename);
  324. X     if (! dirp) {
  325. X      if (! force)
  326. X           fprintf(stderr, "%s: %s not changed\n", whoami, filename);
  327. X      return(ERROR_MASK);
  328. X     }
  329. X     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
  330. X      if (is_dotfile(dp->d_name))
  331. X           continue;
  332. X      if (is_deleted(dp->d_name))
  333. X           continue;
  334. X      else {
  335. X           strcpy(newfile, append(filename, dp->d_name, !force));
  336. X           if (*newfile)
  337. X            status = status | delete(newfile, 1);
  338. X           else
  339. X            status = ERROR_MASK;
  340. X      }
  341. X     }
  342. X     closedir(dirp);
  343. X     status = status | do_move(filename, stat_buf, status);
  344. X     return(status);
  345. X}
  346. X
  347. X                     
  348. X
  349. X
  350. X
  351. X
  352. Xdo_move(filename, stat_buf, err_mask)
  353. Xchar *filename;
  354. Xstruct stat stat_buf;
  355. Xint err_mask;
  356. X{
  357. X     char *last;
  358. X     char buf[MAXPATHLEN];
  359. X     char name[MAXNAMLEN];
  360. X     struct stat deleted_buf;
  361. X
  362. X     strncpy(buf, filename, MAXPATHLEN);
  363. X     last = lastpart(buf);
  364. X     if (strlen(last) > MAXNAMLEN) {
  365. X      if (! force)
  366. X           fprintf(stderr, "%s: %s: filename too long\n", whoami,
  367. X               filename);
  368. X      return(ERROR_MASK);
  369. X     }
  370. X     strcpy(name, last);
  371. X     if (strlen(buf) + 3 > MAXPATHLEN) {
  372. X      if (! force)
  373. X           fprintf(stderr, "%s: %s: pathname too long\n", whoami,
  374. X               filename);
  375. X      return(ERROR_MASK);
  376. X     }
  377. X     *last = '\0';
  378. X     strcat(buf, ".#");
  379. X     strcat(buf, name);
  380. X     if (err_mask) {
  381. X      if (! force)
  382. X           fprintf(stderr, "%s: %s not removed\n", whoami, filename);
  383. X      return(err_mask);
  384. X     }
  385. X     if (interactive) {
  386. X      printf("%s: remove %s? ", whoami, filename);
  387. X      if (! yes())
  388. X           return(NO_DELETE_MASK);
  389. X     }
  390. X     else if ((! force) && ((stat_buf.st_mode & S_IFMT) != S_IFLNK)
  391. X          && access(filename, W_OK)) {
  392. X      printf("%s: override protection %o for %s? ", whoami,
  393. X         stat_buf.st_mode & 0777, filename);
  394. X      if (! yes())
  395. X           return(NO_DELETE_MASK);
  396. X     }
  397. X     if (noop) {
  398. X      fprintf(stderr, "%s: %s would be removed\n", whoami, filename);
  399. X      return(0);
  400. X     }
  401. X     if (! lstat(buf, &deleted_buf))
  402. X      unlink_completely(buf);
  403. X     if (rename(filename, buf)) {
  404. X      if (! force)
  405. X           fprintf(stderr, "%s: %s not removed\n", whoami, filename);
  406. X      return(ERROR_MASK);
  407. X     }
  408. X     else {
  409. X      if (verbose)
  410. X           fprintf(stderr, "%s: %s removed\n", whoami, filename);
  411. X      return(0);
  412. X     }
  413. X}
  414. X
  415. X
  416. X
  417. Xunlink_completely(filename)
  418. Xchar *filename;
  419. X{
  420. X     char buf[MAXPATHLEN];
  421. X     struct stat stat_buf;
  422. X     DIR *dirp;
  423. X     struct direct *dp;
  424. X     int status = 0;
  425. X     
  426. X     if (lstat(filename, &stat_buf))
  427. X      return(1);
  428. X
  429. X     if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) {
  430. X      dirp = opendir(filename);
  431. X      if (! dirp)
  432. X           return(1);
  433. X      readdir(dirp); readdir(dirp); /* get rid of . and .. */
  434. X      for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
  435. X           strcpy(buf, append(filename, dp->d_name, 0));
  436. X           if (! buf) {
  437. X            status = 1;
  438. X            continue;
  439. X           }
  440. X           status = status | unlink_completely(buf);
  441. X      }
  442. X      closedir(dirp);
  443. X      status = status | rmdir(filename);
  444. X      return(status);
  445. X     }
  446. X     else
  447. X      return(unlink(filename) == -1);
  448. X}
  449. X
  450. END_OF_FILE
  451. if test 9801 -ne `wc -c <'delete.c'`; then
  452.     echo shar: \"'delete.c'\" unpacked with wrong size!
  453. fi
  454. # end of 'delete.c'
  455. fi
  456. if test -f 'lsdel.c' -a "${1}" != "-c" ; then 
  457.   echo shar: Will not clobber existing file \"'lsdel.c'\"
  458. else
  459. echo shar: Extracting \"'lsdel.c'\" \(6087 characters\)
  460. sed "s/^X//" >'lsdel.c' <<'END_OF_FILE'
  461. X/*
  462. X * $Source: /mit/jik/src/delete/RCS/lsdel.c,v $
  463. X * $Author: jik $
  464. X *
  465. X * This program is a replacement for rm.  Instead of actually deleting
  466. X * files, it marks them for deletion by prefixing them with a ".#"
  467. X * prefix.
  468. X *
  469. X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
  470. X * For copying and distribution information, see the file "mit-copyright.h."
  471. X */
  472. X
  473. X#if (!defined(lint) && !defined(SABER))
  474. X     static char rcsid_lsdel_c[] = "$Header: lsdel.c,v 1.4 89/03/27 12:07:13 jik Exp $";
  475. X#endif
  476. X
  477. X#include <stdio.h>
  478. X#include <sys/types.h>
  479. X#include <sys/dir.h>
  480. X#include <sys/param.h>
  481. X#include <sys/stat.h>
  482. X#include <strings.h>
  483. X#include "col.h"
  484. X#include "util.h"
  485. X#include "directories.h"
  486. X#include "pattern.h"
  487. X#include "lsdel.h"
  488. X#include "mit-copyright.h"
  489. X
  490. Xchar *malloc(), *realloc();
  491. Xextern int current_time;
  492. X
  493. Xint block_total = 0;
  494. Xint dirsonly, recursive, timev, yield;
  495. Xchar *whoami, *error_buf;
  496. X
  497. Xmain(argc, argv)
  498. Xint argc;
  499. Xchar *argv[];
  500. X{
  501. X     extern char *optarg;
  502. X     extern int optind;
  503. X     int arg;
  504. X
  505. X     whoami = lastpart(argv[0]);
  506. X     error_buf = malloc(strlen(whoami) + MAXPATHLEN + 3);
  507. X     if (! error_buf) {
  508. X      perror(whoami);
  509. X      exit(1);
  510. X     }
  511. X     dirsonly = recursive = timev = yield = 0;
  512. X     while ((arg = getopt(argc, argv, "drt:y")) != -1) {
  513. X      switch (arg) {
  514. X      case 'd':
  515. X           dirsonly++;
  516. X           break;
  517. X      case 'r':
  518. X           recursive++;
  519. X           break;
  520. X      case 't':
  521. X           timev = atoi(optarg);
  522. X           break;
  523. X      case 'y':
  524. X           yield++;
  525. X           break;
  526. X      default:
  527. X           usage();
  528. X           exit(1);
  529. X      }
  530. X     }
  531. X     if (optind == argc) {
  532. X      char *cwd;
  533. X
  534. X      cwd = ".";
  535. X      exit(ls(&cwd, 1));
  536. X     }
  537. X     exit(ls(&argv[optind], argc - optind));
  538. X}
  539. X
  540. X
  541. X
  542. X
  543. X
  544. X
  545. Xusage()
  546. X{
  547. X     printf("Usage: %s [ options ] [ filename [ ...]]\n", whoami);
  548. X     printf("Options are:\n");
  549. X     printf("     -d     list directory names, not contents\n");
  550. X     printf("     -r     recursive\n");
  551. X     printf("     -t n   list n-day-or-older files only\n");
  552. X     printf("     -y     report total space taken up by files\n");
  553. X}
  554. X
  555. X
  556. X
  557. X
  558. Xls(args, num)
  559. Xchar **args;
  560. Xint num;
  561. X{
  562. X     char *start_dir;
  563. X     char **found_files;
  564. X     int num_found, total = 0;
  565. X     char *file_re;
  566. X     int status = 0;
  567. X     
  568. X     if (initialize_tree())
  569. X      exit(1);
  570. X     
  571. X     for ( ; num; num--) {
  572. X      if (*args[num - 1] == '/') {
  573. X           start_dir = "/";
  574. X           file_re = parse_pattern(args[num - 1] + 1);
  575. X      }
  576. X      else {
  577. X           start_dir = "";
  578. X           file_re = parse_pattern(args[num - 1]);
  579. X      }
  580. X      if (! file_re)
  581. X           return(ERROR_MASK);
  582. X
  583. X      found_files = get_the_files(start_dir, file_re, &num_found);
  584. X      free(file_re);
  585. X      total += num_found;
  586. X      if (num_found)
  587. X           num_found = process_files(found_files, num_found);
  588. X      else {
  589. X           /* What we do at this point depends on exactly what the
  590. X            * file_re is.  There are three possible conditions:
  591. X        * 1. It's an existing directory.  Print nothing.
  592. X        * 2. It doesn't exist in deleted form, and there are
  593. X        *    no wildcards in it.  Then we print "not found."
  594. X        * 3. It does't exist, but there are wildcards in it.
  595. X        *    Then we print "no match."
  596. X        * None of these are considered error conditions, so we
  597. X        * don't set the error flag.
  598. X        */
  599. X           if (no_wildcards(file_re)) {
  600. X            if (! directory_exists(args[num - 1])) {
  601. X             fprintf(stderr, "%s: %s: not found\n",
  602. X                 whoami, args[num - 1]);
  603. X            }
  604. X           }
  605. X           else {
  606. X            fprintf(stderr, "%s: %s: no match\n",
  607. X                whoami, args[num-1]);
  608. X           }
  609. X      }
  610. X     }
  611. X     if (total) {
  612. X      list_files();
  613. X     }
  614. X     if (yield)
  615. X      printf("\nTotal space taken up by file%s: %dk\n",
  616. X         (total == 1 ? "" : "s"), blk_to_k(block_total));
  617. X     return(status);
  618. X}
  619. X
  620. X
  621. X
  622. X
  623. Xchar **get_the_files(start_dir, file_re, number_found)
  624. Xchar *start_dir, *file_re;
  625. Xint *number_found;
  626. X{
  627. X     char **matches;
  628. X     int num_matches;
  629. X     char **found;
  630. X     int num;
  631. X     int i;
  632. X
  633. X     found = (char **) malloc(0);
  634. X     num = 0;
  635. X
  636. X     matches = find_matches(start_dir, file_re, &num_matches);
  637. X     if (recursive) {
  638. X      char **recurs_found;
  639. X      int recurs_num;
  640. X
  641. X      for (i = 0; i < num_matches; free(matches[i]), i++) {
  642. X           if (is_deleted(lastpart(matches[i]))) {
  643. X            found = add_str(found, num, matches[i]);
  644. X            num++;
  645. X           }
  646. X           recurs_found = find_deleted_recurses(matches[i], &recurs_num);
  647. X           add_arrays(&found, &num, &recurs_found, &recurs_num);
  648. X      }
  649. X     }
  650. X     else {
  651. X      struct stat stat_buf;
  652. X      char **contents_found;
  653. X      int num_contents;
  654. X      
  655. X      for (i = 0; i < num_matches; free(matches[i]), i++) {
  656. X           if (is_deleted(lastpart(matches[i]))) {
  657. X            found = add_str(found, num, matches[i]);
  658. X            num++;
  659. X           }
  660. X           if (dirsonly)
  661. X            continue;
  662. X           if (lstat(matches[i], &stat_buf))
  663. X            continue;
  664. X           if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) {
  665. X            contents_found = find_deleted_contents_recurs(matches[i],
  666. X                              &num_contents);
  667. X            add_arrays(&found, &num, &contents_found, &num_contents);
  668. X            
  669. X           }
  670. X      }
  671. X     }
  672. X     free(matches);
  673. X     *number_found = num;
  674. X     return(found);
  675. X}
  676. X
  677. X
  678. X
  679. X
  680. X
  681. X
  682. Xprocess_files(files, num)
  683. Xchar **files;
  684. Xint num;
  685. X{
  686. X     int i;
  687. X     filerec *leaf;
  688. X     
  689. X     for (i = 0; i < num; i++) {
  690. X      if (! (leaf = add_path_to_tree(files[i]))) {
  691. X           fprintf(stderr, "%s: error adding path to filename tree\n",
  692. X               whoami);
  693. X           exit(1);
  694. X      }
  695. X
  696. X      free(files[i]);
  697. X      if (! timed_out(leaf, current_time, timev)) {
  698. X           free_leaf(leaf);
  699. X           num--;
  700. X           continue;
  701. X      }
  702. X      block_total += leaf->specs.st_blocks;
  703. X     }
  704. X     free(files);
  705. X     return(num);
  706. X}
  707. X
  708. X
  709. X
  710. X
  711. X
  712. Xlist_files()
  713. X{
  714. X     filerec *current;
  715. X     char **strings;
  716. X     int num;
  717. X
  718. X     strings = (char **) malloc(sizeof(char *));
  719. X     num = 0;
  720. X     if (! strings) {
  721. X      perror(sprintf(error_buf, "%s: list_files", whoami));
  722. X      exit(1);
  723. X     }
  724. X     current = get_root_tree();
  725. X     strings = accumulate_names(current, strings, &num);
  726. X     current = get_cwd_tree();
  727. X     strings = accumulate_names(current, strings, &num);
  728. X     column_array(strings, num, DEF_SCR_WIDTH, 0, 0, 2, 1, 0, 1, stdout);
  729. X     for ( ; num; num--)
  730. X      free(strings[num - 1]);
  731. X     free(strings);
  732. X     return(0);
  733. X}
  734. END_OF_FILE
  735. if test 6087 -ne `wc -c <'lsdel.c'`; then
  736.     echo shar: \"'lsdel.c'\" unpacked with wrong size!
  737. fi
  738. # end of 'lsdel.c'
  739. fi
  740. echo shar: End of archive 3 \(of 6\).
  741. cp /dev/null ark3isdone
  742. MISSING=""
  743. for I in 1 2 3 4 5 6 ; do
  744.     if test ! -f ark${I}isdone ; then
  745.     MISSING="${MISSING} ${I}"
  746.     fi
  747. done
  748. if test "${MISSING}" = "" ; then
  749.     echo You have unpacked all 6 archives.
  750.     rm -f ark[1-9]isdone
  751. else
  752.     echo You still need to unpack the following archives:
  753.     echo "        " ${MISSING}
  754. fi
  755. ##  End of shell archive.
  756. exit 0
  757.  
  758. -- 
  759. Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
  760.  
  761.  
  762.